#include <pthread.h>
#include <iostream>
#include <vector>
#include <queue>
#include <unistd.h>

const int num = 5;

template <typename T>
struct threadPool
{
    static threadPool<T>* construct(const int& n = num)
    {
        if(stp == nullptr)//用来提高效率
        {
            pthread_mutex_lock(&_mtx);
            if(stp == nullptr)
            {
                 stp = new threadPool<T>(num);//new是不需要this指针的，所以可以
            }
            pthread_mutex_unlock(&_mtx);
        }
        return stp;
    }
    static void *threadRoutine(void *args)
    {
        //从任务队列中拿取任务。队列为null，则阻塞
        threadPool<T> *tp = static_cast<threadPool<T> *>(args);
        pthread_detach(pthread_self()); // 线程分离，不用手动join线程。

        while (1)
        {
            pthread_mutex_lock(&tp->_mtx);
            while (tp->_task.empty())
                pthread_cond_wait(&tp->_cond, &tp->_mtx);

            std::cout << pthread_self() << "Runing:" << tp->_task.front() << std::endl;//处理任务
            
            tp->_task.pop();
            pthread_mutex_unlock(&tp->_mtx);
        }
    }
    void pushTask(const T &task)
    {
        pthread_mutex_lock(&_mtx);
        _task.push(task);
        pthread_cond_signal(&_cond);    //唤醒线程
        pthread_mutex_unlock(&_mtx);
    }
    void start()
    {
        //程序启动，创建num个线程，并执行对应方法
        for (int i = 0; i < num; i++)
        {
            pthread_create(&_threads[i], NULL, threadRoutine, this);
        }
    }
    ~threadPool()
    {
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_cond);
    }

private:
    threadPool(int size)
        : _cap(size)
    {
        _threads.resize(_cap);
        pthread_mutex_init(&_mtx, NULL);
        pthread_cond_init(&_cond, NULL);
    }

private:
    //vector存放thread ID ,_task 存放任务
    std::vector<pthread_t> _threads;
    int _cap;
    std::queue<int> _task;
    pthread_mutex_t _mtx;
    pthread_cond_t _cond;

    static threadPool<T>* stp;
};

template<class T>
threadPool<T>* threadPool<T>::stp = nullptr;